<?php

// +----------------------------------------------------------------------
// | H1CMS © OpenSource CMS
// +----------------------------------------------------------------------
// | Copyright (c) 2014-2016 http://www.h1cms.com All rights reserved.
// | Copyright (c) 2014-2016 嘉兴领格信息技术有限公司，并保留所有权利。
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: Allen <allen@lg4.cn>
// +----------------------------------------------------------------------

namespace h1cms;

use ArrayAccess;
use Lg\Config;

/**
 * 
 * H1CMS  
 * @property \Lg\Database\Database $db The database connection. 
 * @property \Lg\Http\Request $req The request component. 
 * @property \Lg\Http\Response $resp The response component. 
 * @property \h1cms\system\Screen $screen The Screen component. 
 *
 * @author Allen <allen@lg4.cn>
 */
class H1 implements ArrayAccess {

    protected $_data = array();

    /**
     *
     * @var \h1cms\H1
     */
    public static $app;

    public function offsetExists($offset) {
        return array_key_exists($offset, $this->_data);
    }

    public function offsetGet($offset) {
        return $this->_data[$offset];
    }

    public function __get($name) {
        switch ($name) {
            case 'db':
                static::$app->db = \Lg\Database\Database::getConnection();
                return static::$app->db;
            case 'req':
                static::$app->req = \Lg\Http\Request::classic();
                return static::$app->req;
            case 'resp':
                static::$app->resp = \Lg\Http\Response::make();
                return static::$app->resp;
            case 'screen':
                static::$app->screen = new system\Screen();
                return static::$app->screen;
        }

        $components = Config::get('config.components');
        if (isset($components[$name])) {
            $component = $components[$name];
            $params = [];
            if (is_string($component)) { //class name
                $className = $component;
            } elseif (is_array($component) && isset($component['class'])) {
                $className = $component['class'];
                unset($component['class']);
                $params = $component;
            } elseif (is_callable($component, true)) {
                static::$app->{$name} = call_user_func($component);
                return static::$app->{$name};
            } else {
                throw new \RuntimeException('Unsupported configuration type: ' . gettype($type));
            }
            static::$app->{$name} = static::createObject($className, $params);
            return static::$app->{$name};
        }
    }

    public function offsetSet($offset, $value) {
        $this->_data[$offset] = $value;
    }

    public function offsetUnset($offset) {
        unset($this->_data[$offset]);
    }

    public static function createObject($class, $params = []) {
        $object = new \ReflectionClass($class);
        return $object->newInstanceArgs($params);
    }

}
